﻿using Abp.Application.Services;
using Abp.Application.Services.Dto;
using Abp.Domain.Repositories;
using AutoMapper;
using Sunlit.House.Regions.Dto;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Abp.Linq.Extensions;
using Sunlit.House.Helper;

namespace Sunlit.House.Regions
{
    public class RegionAppService : AsyncCrudAppService<Region,
        RegionDto,
        int,
        GetAllRegionsInput,
        CreateRegionInput,
        UpdateRegionInput>, IRegionAppService
    {
        public RegionAppService(IRepository<Region> repository) : base(repository)
        {
            
        }
        protected override IQueryable<Region> CreateFilteredQuery(GetAllRegionsInput input)
        {
            //TODO: 大概有问题
            return base.CreateFilteredQuery(input)
                .WhereIf(!string.IsNullOrEmpty(input.Name), r => r.Name.Contains(input.Name))
                .WhereIf(input.ParentId.HasValue && input.ParentId.Value == 0, r => r.ParentId == null)
                .WhereIf(input.ParentId.HasValue && input.ParentId.Value != 0, r => r.ParentId == input.ParentId)
                .WhereIf(input.IsHot.HasValue, r => r.IsHot == input.IsHot);
        }
        /// <summary>
        /// /获取级联数据
        /// </summary>
        /// <returns>级联数据</returns>
        public async Task<List<ValueLabelCasCadeItem>> GetCasCadeData()
        {
            var allRegions = await Repository.GetAllListAsync();
            var firstCasCade = allRegions.Where(r => r.ParentId == null)
                .Select(r =>
                {
                    if (allRegions.Any(x => x.ParentId == r.Id))
                    {
                        return new ValueLabelChildCasCadeItem
                        {
                            Value = r.Id,
                            Label = r.Name
                        };
                    }
                    else
                    {
                        return new ValueLabelCasCadeItem
                        {
                            Value = r.Id,
                            Label = r.Name
                        };
                    }

                }).ToList();

            foreach (var item in firstCasCade)
            {
                if (allRegions.Any(x => x.ParentId == item.Value))
                {
                    (item as ValueLabelChildCasCadeItem).Children = allRegions.Where(r => r.ParentId.HasValue && r.ParentId.Value == item.Value)
                    .Select(r =>
                    {
                        if (allRegions.Any(x => x.ParentId == r.Id))
                        {
                            return new ValueLabelChildCasCadeItem
                            {
                                Value = r.Id,
                                Label = r.Name
                            };
                        }
                        else
                        {
                            return new ValueLabelCasCadeItem
                            {
                                Value = r.Id,
                                Label = r.Name
                            };
                        }

                    }).ToList();

                    foreach (var it in (item as ValueLabelChildCasCadeItem).Children)
                    {
                        if (allRegions.Any(x => x.ParentId == it.Value))
                        {
                            (it as ValueLabelChildCasCadeItem).Children = allRegions.Where(r => r.ParentId.HasValue && r.ParentId.Value == it.Value)
                            .Select(r =>
                            {
                                return new ValueLabelCasCadeItem
                                {
                                    Value = r.Id,
                                    Label = r.Name
                                };
                            }).ToList();
                        }

                    }
                }


            }

            return firstCasCade;
        }
        /// <summary>
        /// 获取级联数据id
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<List<int>> GetCasCadeIdById(int id)
        {
            List<int> lst = new List<int>();
            await GetCasCadeId(lst, id);
            return lst;
        }
        private async Task GetCasCadeId(List<int> lst, int id)
        {
            var thirdItem = await this.GetAsync(new EntityDto<int>(id));
            
            lst.Insert(0, thirdItem.Id);
            if (thirdItem.ParentId.HasValue)
            {
                await GetCasCadeId(lst, thirdItem.ParentId.Value);
            }
        }
        /// <summary>
        /// 获取所有子节点ID和自身ID的列表
        /// </summary>
        /// <param name="idList"></param>
        /// <param name="id"></param>
        private void GetAllChildId(List<int> idList, int id)
        {
            idList.Add(id);
            var tempList = Repository.GetAllList(rx => rx.ParentId == id);
            if (tempList.Count > 0)
            {
                foreach (var item in tempList)
                {
                    GetAllChildId(idList, item.Id);
                }
            }
        }

        /// <summary>
        /// 获取树形结构的数据
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<List<RegionDto>> GetTreeData(GetTreeDataInput input)
        {
            var allRegions = ObjectMapper.Map<List<RegionDto>>(await Repository.GetAllListAsync());
            if (!string.IsNullOrEmpty(input.Name))
            {
                allRegions = allRegions.Where(r => r.Name.Contains(input.Name)).ToList();
            }
            var rootRegions = allRegions.Where(r => r.ParentId == null).ToList();
            AddTreeNode(rootRegions, allRegions);

            return rootRegions;

        }
        private void AddTreeNode(List<RegionDto> rootRegions, List<RegionDto> allRegions)
        {
            foreach (var rootRegion in rootRegions)
            {
                if (allRegions.Any(r => r.ParentId == rootRegion.Id))
                {
                    rootRegion.Children = allRegions.Where(rx => rx.ParentId == rootRegion.Id).ToList();
                    AddTreeNode(rootRegion.Children, allRegions);
                }
            }
        }
        /// <summary>
        /// 重写父类方法
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public override async Task<RegionDto> CreateAsync(CreateRegionInput input)
        {
            if (input.ParentId.HasValue)
            {
                var parent = await this.GetAsync(new EntityDto<int>(input.ParentId.Value));
                input.Layer = parent.Layer + 1;
                if (input.Layer == 2)
                {
                    input.ProvinceId = parent.Id;
                    input.ProvinceName = parent.Name;

                    input.FullName = parent.Name + "-" + input.Name;
                }
                if (input.Layer == 3)
                {
                    input.ProvinceId = parent.ProvinceId;
                    input.ProvinceName = parent.ProvinceName;
                    input.CityId = parent.Id;
                    input.CityName = parent.Name;

                    input.FullName = parent.ProvinceName + "-" + parent.Name + "-" + input.Name;
                }
            }
            else
            {
                input.Layer = 1;
                input.FullName = input.FullName;
            }
            input.ShortSpell = PinyinHelper.GetFirstLetter(input.Name);
            return await base.CreateAsync(input);
        }
        public override Task<RegionDto> UpdateAsync(UpdateRegionInput input)
        {
            input.ShortSpell = PinyinHelper.GetFirstLetter(input.Name);
            return base.UpdateAsync(input);
        }
        /// <summary>
        /// 获取所有省
        /// </summary>
        /// <returns></returns>
        public async Task<List<RegionDto>> GetProvincesAsync()
        {
            var list = await Repository.GetAllListAsync(r => r.Layer == 1);
            return ObjectMapper.Map<List<RegionDto>>(list);
        }
        /// <summary>
        /// 获取所有市
        /// </summary>
        /// <param name="provinceId"></param>
        /// <returns></returns>
        public async Task<List<RegionDto>> GetCitiesAsync(int provinceId)
        {
            var list = await Repository.GetAllListAsync(r => r.Layer == 2 && r.ProvinceId == provinceId);
            return ObjectMapper.Map<List<RegionDto>>(list);
        }
        public async Task<List<FirstLetterOutput>> GetAllCitiesGroupByFirstLetter()
        {
            var list = await Repository.GetAllListAsync(r => r.Layer == 2);
            var listDto = ObjectMapper.Map<List<RegionDto>>(list);
            var dicGroup = listDto.GroupBy(r => r.ShortSpell).OrderBy(g => g.Key)
                .Select(g => new FirstLetterOutput
                {
                    Key = g.Key,
                    items = g.ToList()
                }).ToList();

            return dicGroup;
        }
        /// <summary>
        /// 获取热门地区
        /// </summary>
        /// <returns></returns>
        public async Task<List<RegionDto>> GetHotRegionsAsync()
        {
            var list = await Repository.GetAllListAsync(r => r.IsHot);
            return ObjectMapper.Map<List<RegionDto>>(list);
        }
        public RegionDto GetRegionByName(string name)
        {
            var r = Repository.GetAll().FirstOrDefault(r => r.Name == name);
            return ObjectMapper.Map<RegionDto>(r);
        }
    }
}
